/**
 * 作者:hanbo
 * 日期:2018/12/69:27
 * 描述:多折点线路
 */
import {Geometry} from "./Geometry";
import {BoundingBox} from "./BoundingBox";
import {EXTENDS_3857} from "../core/Constant";

export class Polyline extends Geometry {
    /**
     * 构造器
     * @param array {Array} 二维点数组[[x1,y1],[x2,y2]]
     */
    constructor(array) {
        super("polyline", BoundingBox.getPolylineBox(array));
        this.path = array;
    }

    /**
     * 设置多段线样式
     * @param lineStyle {LineStyle} 线样式
     */
    setStyle(lineStyle) {
        super.setStyle(lineStyle)
    }

    /**
     * 插入点
     * @param point {Point} 待插入点
     * @param index {Number} 插入位置,插入后变成索引
     */
    addPoint(point, index) {
        this.path.splice(index, 0, [point.x, point.y]);
        this.box.addBox(point.box);
    }

    /**
     * 删除折线的第几个点
     * @param index
     */
    removePoint(index) {
        if (this.box.xMin === this.path[index][0]
            || this.box.xMax === this.path[index][0]
            || this.box.yMin === this.path[index][1]
            || this.box.yMax === this.path[index][1]
        ) {
            this.path.splice(index, 1);
            //重新计算外接矩形
            this.box = BoundingBox.getPolylineBox(this.path)
        }
        else {
            this.path.splice(index, 1)
        }
    }

    /**
     * 转到GL绘图坐标系
     */
    toGLCoordinate() {
        if (!this._glPath) {
            this._glPath = [];
            for (let i = 0; i < this.path.length; i++) {
                this._glPath.push([this.path[i][0] / EXTENDS_3857, this.path[i][1] / EXTENDS_3857])
            }
        }
    }

    static randomPolyline() {
        let path = [];
        let pointCount = Math.round(Math.random() * 3) + 2;//随机2-5个点
        // let pointCount = 3;//随机3个点
        for (let i = 0; i < pointCount; i++) {
            let numX = Math.random() * 2 - 1;//-1到1随机数
            let numY = Math.random() * 2 - 1;//-1到1随机数
            path.push([numX * EXTENDS_3857, numY * EXTENDS_3857])
        }
        return new Polyline(path);
    }

    /**
     * 多段线转面
     * @param coordinates {Number[][]} 中心线,二维点数组形式
     * @param width {Number} 线宽度
     * @return {Number[][]} 条带装坐标1-2-4-3
     */
    static toArea(coordinates, width) {
        const dis = width / 2;//向两侧扩展，每侧为1/2宽度
        /**
         * 获取以第一点为中心向左旋转90度的指定长度向量向量
         */
        function getLeftVector(x1, y1, x2, y2,dis) {
            let vector = [x2 - x1, y2 - y1];//向量
            let model = getModel(vector);//取模
            let unitVector = [vector[0] / model, vector[1] / model];//单位向量
            return [-unitVector[1]*dis, unitVector[0]*dis]//[x*cosA-y*sinA  x*sinA+y*cosA]
        }


        /**
         * 计算二维向量的模
         * @param vector {Number[]} 二维向量
         */
        function getModel(vector) {
            return Math.sqrt(Math.pow(vector[0], 2) + Math.pow(vector[1], 2))
        }

        /**
         * 通过向量计算两条线之间的夹角
         * @param x1
         * @param y1
         * @param x2
         * @param y2
         * @param x3
         * @param y3
         * @param dis {Number} 宽度
         * @return {Number[]} 向量
         */
        function getCenterVector(x1, y1, x2, y2, x3, y3,dis) {
            let vector1 = [x2 - x1, y2 - y1];
            let vector2 = [x2 - x3, y2 - y3];

            let model1=getModel(vector1);
            let model2=getModel(vector2);
            //求向量夹角
            let cos=(vector1[0]*vector2[0]+vector1[1]*vector2[1])/(model1*model2);
            let radian=Math.acos(cos);
            let width=dis/Math.sin(radian/2);//计算拐点处宽度
            let vector1_unit=[vector1[0]/model1,vector1[1]/model1];
            let vector2_unit=[vector2[0]/model2,vector2[1]/model2];
            let vector3=[vector1_unit[0]+vector2_unit[0],vector1_unit[1]+vector2_unit[1]];
            let model3=getModel(vector3);

            let vector_left=getLeftVector(x1, y1, x2, y2,dis);
            if((vector_left[0]*vector3[0]+vector_left[1]*vector3[1])>0){
                return [vector3[0]/model3*width,vector3[1]/model3*width];
            }else {
                return [-vector3[0]/model3*width,-vector3[1]/model3*width];
            }
        }

        let path = [];
        let vector = getLeftVector(coordinates[0][0], coordinates[0][1], coordinates[1][0], coordinates[1][1],dis);
        path.push([coordinates[0][0] + vector[0], coordinates[0][1] + vector[1]], [coordinates[0][0] - vector[0], coordinates[0][1] - vector[1]]);
        //循环绘制中间点
        let lastIndex=coordinates.length-1;
        for (let i = 1; i < lastIndex; i++) {
            vector = getCenterVector(coordinates[i - 1][0], coordinates[i - 1][1], coordinates[i][0], coordinates[i][1], coordinates[i + 1][0], coordinates[i + 1][1], dis);
            path.push([coordinates[i][0]+vector[0], coordinates[i][1]+vector[1]],[coordinates[i][0]-vector[0], coordinates[i][1]-vector[1]]);
        }

        vector = getLeftVector(coordinates[lastIndex-1][0], coordinates[lastIndex-1][1], coordinates[lastIndex][0], coordinates[lastIndex][1],dis);
        path.push([coordinates[lastIndex][0] + vector[0], coordinates[lastIndex][1] + vector[1]], [coordinates[lastIndex][0] - vector[0], coordinates[lastIndex][1] - vector[1]]);
        return path;
    }
}